#pragma once
#include "Interface.h"
#include "Route.h"

//===========================================================================
// Player
//===========================================================================
class Player : public IPlayer
{
public :
    
    Player(
        EPieceType piece,
        IBoard *   board
    );

    bool Move( void );

    void Release( void );

protected :

    EPieceType m_piece;
    IBoard *   m_board;

private :

    bool Move(
        IPosition & position,
        ECourse     course
    );

    bool TryToJump(
        IPosition & position,
        ECourse     course
    );

    ECourse CanJumpAgain(
        IPosition & position
    );
    bool CanJumpAgain(
        IPosition & position,
        ECourse     course
    );

    bool GetDestPosition(
        const IPosition & position,
              ECourse     course,
              Position &  dest
    );

    const EPieceType * GetDest(
        IPosition & position,
        ECourse     course,
        Position &  dest
    );

    bool GetUserMoveCommand(
        Position & position,
        ECourse &  course,
        bool &     giveup
    );
    
    bool GetUserCourseCommand(
        ECourse & course
    );
    
    bool StringToCourse(
        const char *    str,
              ECourse & course
    );

    static void Release(
        Player * player
    );
};


//===========================================================================
// PlayerAI
//===========================================================================
class PlayerAI : public Player
{
public :    
    
    PlayerAI(
        EPieceType piece,
        IBoard *   board
    );

    bool Move( void );

    void Release( void );

private :

    typedef std::vector< Route > Routes;
    
    void FindBestRoutes(
        Routes & routes
    );
        
    bool Move(
        Route & route
    );
    
    bool Move(
        const IPosition & from,
        const IPosition & to
    );

    const Route * FindDeepestNode(
        const Route * route
    );

    static void Release(
        PlayerAI * player
    );
};